package com.zdp.leetcode;
/*
* 题目描述：
* 对于一个压缩字符串，设计一个数据结构，它支持如下两种操作： next 和 hasNext。
给定的压缩字符串格式为：每个字母后面紧跟一个正整数，这个整数表示该字母在解压后的字符串里连续出现的次数。
next() - 如果压缩字符串仍然有字母未被解压，则返回下一个字母，否则返回一个空格。
hasNext() - 判断是否还有字母仍然没被解压。
注意：
请记得将你的类在 StringIterator 中 初始化 ，因为静态变量或类变量在多组测试数据中不会被自动清空。更多细节请访问 这里 。
示例：
StringIterator iterator = new StringIterator("L1e2t1C1o1d1e1");
iterator.next(); // 返回 'L'
iterator.next(); // 返回 'e'
iterator.next(); // 返回 'e'
iterator.next(); // 返回 't'
iterator.next(); // 返回 'C'
iterator.next(); // 返回 'o'
iterator.next(); // 返回 'd'
iterator.hasNext(); // 返回 true
iterator.next(); // 返回 'e'
iterator.hasNext(); // 返回 false
iterator.next(); // 返回 ' '
来源：力扣（LeetCode）
链接：https://leetcode-cn.com/problems/design-compressed-string-iterator
著作权归领扣网络所有。商业转载请联系官方授权，非商业转载请注明出处。
* */

public class 迭代压缩字符串 {
    public static void main(String[] args) {
        StringIterator1 s = new StringIterator1("L1e2t1C1o1d1e1");
        System.out.println(s.next());
        System.out.println(s.next());
        System.out.println(s.next());
        System.out.println(s.next());
        System.out.println(s.next());
        System.out.println(s.next());
        System.out.println(s.hasNext());
        System.out.println(s.next());
        System.out.println(s.hasNext());
    }
}
//我这边的解题思路就是： 因为题目输入的压缩字符串 是一个字符 后面跟着该字符出现的次数
//所以 我用一个temp 来存储当前要输出的字符  用 length 来存储该字符还需要输出的次数，每次输出字符，length--
//用length==0 来判断 字符是否已经输出完毕
//若字符输出完毕，就要得到下一个要输出的字符了
//我的这个思路 就是官方解法3
class StringIterator {
    String compressedString;
    int index;
    char temp;
    int length;
    public StringIterator(String compressedString) {
        this.compressedString = compressedString;
        index = 0;
        length = 0;
        temp = ' ';
    }

    public char next() {
        if(index>=compressedString.length()&&length==0)
            return ' ';
        if(length==0){
            //说明已经输出完毕了
            //可以进行下一个了
            //得到要输出的字符 和 字符要输出的次数
            temp = compressedString.charAt(index++);
            char c = compressedString.charAt(index);
            while(Character.isDigit(c)){
                length = length*10 + (c-'0');
                index++;
                if(index==compressedString.length())
                    break;
                c = compressedString.charAt(index);
            }
        }
        length--;
        return temp;
    }

    public boolean hasNext() {
        if(index>=compressedString.length()&&length==0)
            return false;
        return true;
    }
}
//官网的第一个个题解 ===>先根据压缩字符串 来构建出一个要输出的字符串 然后进行输出
//这个题解 会造成内存溢出 。。。。。
class StringIterator1 {
    int ptr=0;
    StringBuffer res = new StringBuffer();
    public StringIterator1(String compressedString) {
        int index=0;
        while(index<compressedString.length()){
            char temp = compressedString.charAt(index++);
            int length = 0;
            //计算长度
            while(index<compressedString.length()&&Character.isDigit(compressedString.charAt(index))){
                length = length*10+(compressedString.charAt(index)-'0');
                index++;
            }
            for(int i=0;i<length;i++){
                res.append(temp);
            }
        }
        System.out.println(res);
    }

    public char next() {
        if(hasNext()){
            return res.charAt(ptr++);
        }
        return ' ';
    }

    public boolean hasNext() {
        if(ptr<res.length())
            return true;
        return false;
    }
}
//官方解法2 ===> 将压缩字符串的 字符 和 数字提取出来 分别存放在两个 数组中
// 每输出一次字符 该字符对应的长度数组的值就减- 当 长度为0 时， 指针指向下一个字符
//他这边提取字符和数字 使用到了正则表达式
//复习一手正则表达式
/*
* public StringIterator(String compressedString) {
        nums = Arrays.stream(compressedString.substring(1).split("[a-zA-Z]+")).mapToInt(Integer::parseInt).toArray();;
        chars = compressedString.split("[0-9]+");
    }

* */
